/* eslint-disable require-jsdoc */
/* eslint-disable no-unused-vars */
class NewPromise {
  constructor(func) {
    this.status = 'pending'
    this.data = undefined
    this.reason = undefined
    this.onRejectedCb = []
    this.onResolvedCb = []
    const that = this
    function resolve (value) {
      if (that.status !== 'pending') {
        return
      }
      that.status = 'resolved'
      that.data = value
      for (let i = 0; i < that.onResolvedCb.length; i++) {
        that.onResolvedCb[i](value)
      }
    }
    const reject = (reason) => {
      if (this.status !== 'pending') {
        return
      }
      this.status = 'rejected'
      this.reason = reason
      for (let i = 0; i < this.onRejectedCb.length; i++) {
        this.onRejectedCb[i](reason)

      }

    }
    try {
      func(resolve, reject)
    } catch (error) {
      reject(error)
    }
  }
  then(onResolved, onRejected) {
    let promise2
    onResolved = typeof onResolved === 'function' ? onResolved : function() {}
    onRejected = typeof onRejected === 'function' ? onRejected : function() {}
    if (this.status === 'resolved') {
      // 如果promise1的状态已经确定并且是resolved，我们调用onResolved，考虑到有可能throw，所以还需要将其包在try/catch块里
      return (promise2 = new NewPromise((resolve, reject) => {
        try {
          const x = onResolved(this.data)
          if (x instanceof Promise) {
            // 如果onResolved的返回值是一个Promise对象，直接取它的结果作为promise2的结果
            x.then(resolve, reject)
          }
          resolve(x) // 否则，以它的返回值作为promise2的结果
        } catch (e) {
          reject(e) // 如果出错，以捕获到的错误作为promise2的结果
        }
      }))
    }
    // 此处与前一个if块的逻辑几乎相同，区别在于所调用的是onRejected函数
    if (this.status === 'rejected') {
       promise2 = new NewPromise((resolve, reject) => {
        try {
          const x = onResolved(this.data)
          if (x instanceof Promise) {
            // 如果onResolved的返回值是一个Promise对象，直接取它的结果作为promise2的结果
            x.then(resolve, reject)
          }
        } catch (e) {
          reject(e)
        }
      })
      return promise2
    }
    if (this.status === 'pending') {
      // 如果当前的Promise还处于pending状态，我们并不能确定调用onResolved还是onRejected，只能等到Promise的状态确定后，才能确定如何处理

      return (promise2 = new NewPromise((resolve, reject) => {
        this.onResolvedCb.push((value) => {
          try {
            const x = onResolved(value)
            if (x instanceof Promise) {
              x.then(resolve, reject)
            }
          } catch (e) {
            reject(e)
          }
        })
        this.onRejectedCb.push((reason) => {
          try {
            const x = onRejected(reason)
            if (x instanceof Promise) {
              x.then(resolve, reject)
            }
          } catch (e) {
            reject(e)
          }
        })
      }))
    }

  }
  catch(onRejected) {
    return this.then(undefined, onRejected)

  }
}
export default NewPromise
